﻿using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Exceptions;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Dysmsapi.Model.V20170525;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Xms.Abp.Data.Message;

namespace Xms.Abp.Smsing.Aliyun;

public class AliyunTemplateSmsSenderProvider : TemplateSmsSenderProviderBase, ITemplateSmsSenderProvider, ITransientDependency
{
    protected AliyunSmsSettings AliyunSmsSettings { get; }
    public AliyunTemplateSmsSenderProvider(
        SmsSettings smsSettings,
        AliyunSmsSettings aliyunSmsSettings)
        : base(smsSettings, aliyunSmsSettings)
    {
        AliyunSmsSettings = aliyunSmsSettings;
    }
    public override string ProviderName => "Aliyun";

    public override async Task<SentResult<SmsSentResultItem>> SendSmsAsync(SmsMessage smsMessage)
    {
        var clientProfile = DefaultProfile.GetProfile("cn-hangzhou", AliyunSmsSettings.SecretId, AliyunSmsSettings.SecretKey);
        clientProfile.AddEndpoint("cn-hangzhou", "cn-hangzhou", "Dysmsapi", "dysmsapi.aliyuncs.com");
        var client = new DefaultAcsClient(clientProfile);
        await Task.CompletedTask;
        var templateCode = AliyunSmsSettings.SmsCodes[smsMessage.TemplateCode];
        var request = new SendSmsRequest
        {
            PhoneNumbers = string.Join(",", smsMessage.PhoneNumbers),
            SignName = AliyunSmsSettings.Sign,
            TemplateCode = templateCode,
            TemplateParam = JsonConvert.SerializeObject(smsMessage.TemplateParameters),
        };
        try
        {
            var response = client.GetAcsResponse(request);
            var requestId = response.RequestId;
            var result = new SentResult<SmsSentResultItem>
            {
                RequestId = response.RequestId,
                ProviderName = ProviderName,
                Sign = AliyunSmsSettings.Sign,
                Items = smsMessage.PhoneNumbers.Select(r =>
                new SmsSentResultItem
                {
                    PhoneNumber = r,
                    BizId = response.BizId,
                    ErrorCode = response.Code,
                    Message = response.Message,
                    SentStatus = response.Code == "OK" ? SentStatus.Sending : SentStatus.Faild
                }),
            };
            return result;
        }
        catch (ServerException)
        {
            throw;
        }
        catch (ClientException)
        {
            throw;
        }
    }
}
